import * as THREE from 'three';
import snow from '@/assets/imgs/map/snow.png';
import 云朵 from '@/assets/imgs/map/云朵.png';
import rain from '@/assets/imgs/map/rain.png';
/**
 * Three.js 天气系统示例 (晴天/多云/阴天/雨天/雪天)
 * 核心思路：配置驱动 + 职责分离 + 灯光与粒子统一管理
 */

// 全局配置
const WEATHER_CONFIG = {
	sunny: {
		background: 0x87ceeb,
		lights: [
			{
				type: 'DirectionalLight',
				color: 0xffffff,
				intensity: 2,
				castShadow: true,
				position: [0, 100, 0],
			},
		],
	},
	cloudy: {
		background: 0xc2d5dc,
		lights: [
			{ type: 'AmbientLight', color: 0xffffff, intensity: 0.5 },
			{
				type: 'DirectionalLight',
				color: 0xffffff,
				intensity: 1.0,
				castShadow: true,
				position: [50, 80, 0],
			},
		],
	},
	overcast: {
		background: 0xa7b8c4,
		lights: [{ type: 'AmbientLight', color: 0xffffff, intensity: 0.7 }],
	},
	rain: {
		background: 0xbcc7cc,
		lights: [{ type: 'AmbientLight', color: 0xffffff, intensity: 1.0 }],
		particle: {
			map: rain,
			count: 15000,
			size: 2,
			area: { x: 500, y: 400, z: 500 },
			speed: 50,
			opacity: 0.7,
		},
	},
	snow: {
		background: 0xc8e4fa,
		lights: [{ type: 'AmbientLight', color: 0xffffff, intensity: 1.0 }],
		particle: {
			map: snow,
			count: 10000,
			size: 5,
			area: { x: 500, y: 400, z: 500 },
			speed: 20,
			opacity: 0.9,
			rotationSpeed: 0.01,
		},
	},
};

// 管理全局对象
let currentWeatherGroup = null;
let currentLightGroup = null;
let rafId = null;
const clock = new THREE.Clock();

// 清除旧天气及旧光源
function clearWeather(scene) {
	// 移除粒子组
	if (currentWeatherGroup) {
		scene.remove(currentWeatherGroup);
		currentWeatherGroup = null;
	}
	// 移除光源
	if (currentLightGroup) {
		scene.remove(currentLightGroup);
		currentLightGroup = null;
	}
	// 取消动画
	if (rafId) {
		cancelAnimationFrame(rafId);
		rafId = null;
	}
}

// 创建并挂载光源组
function applyLights(lights, scene) {
	const group = new THREE.Group();
	lights.forEach((cfg) => {
		let light;
		if (cfg.type === 'DirectionalLight') {
			light = new THREE.DirectionalLight(cfg.color, cfg.intensity);
			if (cfg.castShadow) light.castShadow = true;
			if (cfg.position) light.position.fromArray(cfg.position);
		} else {
			light = new THREE[cfg.type](cfg.color, cfg.intensity);
		}
		group.add(light);
	});
	scene.add(group);
	currentLightGroup = group;
}

// 创建粒子系统
function createParticles(cfg) {
	const { count, area, map, size, opacity, speed } = cfg;
	const pos = new Float32Array(count * 3);
	const vel = new Float32Array(count);
	for (let i = 0; i < count; i++) {
		pos[3 * i] = (Math.random() - 0.5) * area.x;
		pos[3 * i + 1] = Math.random() * area.y;
		pos[3 * i + 2] = (Math.random() - 0.5) * area.z;
		vel[i] = speed * (0.8 + Math.random() * 0.4);
	}
	const geo = new THREE.BufferGeometry();
	geo.setAttribute('position', new THREE.BufferAttribute(pos, 3));
	geo.setAttribute('velocity', new THREE.BufferAttribute(vel, 1));

	const mat = new THREE.PointsMaterial({
		map: new THREE.TextureLoader().load(map),
		size,
		sizeAttenuation: true,
		transparent: true,
		opacity,
		depthWrite: false,
	});
	return new THREE.Points(geo, mat);
}

// 核心函数：切换天气
function createWeather(type = 'sunny', scene) {
	clearWeather(scene);

	const cfg = WEATHER_CONFIG[type];
	if (!cfg) {
		console.warn('Unsupported weather type:', type);
		return;
	}

	// 背景
	scene.background = new THREE.Color(cfg.background);

	// 光源
	applyLights(cfg.lights, scene);

	// 粒子组
	const group = new THREE.Group();
	if (cfg.particle) {
		const pts = createParticles(cfg.particle);
		group.add(pts);
	}
	scene.add(group);
	currentWeatherGroup = group;

	// 动画
	(function animate() {
		const delta = clock.getDelta();
		group.children.forEach((obj) => {
			if (obj.isPoints) {
				const posArr = obj.geometry.attributes.position.array;
				const velArr = obj.geometry.attributes.velocity.array;
				for (let i = 0; i < velArr.length; i++) {
					posArr[3 * i + 1] -= velArr[i] * delta;
					if (posArr[3 * i + 1] < 0) {
						posArr[3 * i + 1] = cfg.particle.area.y;
						posArr[3 * i] = (Math.random() - 0.5) * cfg.particle.area.x;
						posArr[3 * i + 2] = (Math.random() - 0.5) * cfg.particle.area.z;
					}
				}
				obj.geometry.attributes.position.needsUpdate = true;
				if (cfg.particle.rotationSpeed) {
					obj.material.rotation =
						(obj.material.rotation || 0) + cfg.particle.rotationSpeed;
				}
			}
		});
		rafId = requestAnimationFrame(animate);
	})();
}

// 使用示例：
// createWeather('sunny');
// createWeather('cloudy');
// createWeather('overcast');
// createWeather('rain');
// createWeather('snow');

export { clearWeather, createWeather };
